#include <stdio.h> //标准输入输出流头文件

int main() // 一个程序只有一个main函数 是程序的入口
{
/*数据类型*/

/*整型*/
#if 0
    int a = 10; // 整型变量
    short b;    // 短整型
    long c;     // 长整型

    // sizeof 计算一个变量的内存大小 单位：字节

    printf("int : %ld\n",sizeof(int));     // 0~2^32-1
    printf("short : %ld\n",sizeof(short)); // 0~2^16-1
    printf("long : %ld\n",sizeof(long));   //0~2^64-1
    printf("char : %ld\n",sizeof(char));   //0~2^8-1（0~255）
#endif


/*字符型*/
#if 0
    char c = '\n';      //单个字符用单引号括起来
    printf("%d\n",c);   //打印整型数据
    printf("%c",c);     //打印字符  

    //ASCII码表
    //char型数据本质上内存存的是整型数据，打印看以整型数据输出还是字符型数据输出
    // 10 -> '\n'
    // 48 -> '0'
    // 65 -> 'A'
    // 97 -> 'a'
#endif


/*负数如何表示？*/
    /*  
        计算机里只有0和1，不认负号
        0000 0001   1
      + 1000 0001   -1（原码）
        1000 0010   -2（相加不为0？）

        0000 0001
      + 1111 1111   ：（补码）
        0000 0000   溢出

        为了解决计算机正负数加法的问题，把负数的表示形式从原码变成补码（让数据有所谓的溢出）
        计算机存的所有数据都是补码
        正数的补码是其本身
        负数的补码 = 原码取反 + 1
        符号位不参与取反，但参与计算

        1000 0001   原码
        1111 1110   反码
        1111 1111   补码

        char：无符号表示范围0~255 共256个数
        正数：0111 1111 （127）
        负数：1111 1111 （-127）
        所以得到的有符号char的范围是：-127~127 共255个数，少一个？
    */
#if 0
    char c = 129;
    printf("%d\n",c);
#endif

#if 0
    int a = 129;  //000...1000 0001
    char c = a;         //1000 0001 补码（取反 +1）
                        //1000 0000 反码
                        //1111 1111 原码（-127）
    //将整型变量赋给char,前面24位被截断，char接到的数据是最后8位1000 0001，其本质上是个补码，原来的符号位0丢失，现在的最高位1被看作是符号位，所以是一个负数
    //所以之所以说C语言是一门弱类型的语言，是因为其没有数据上溢一说，对它来说只不过是全部的1变为全部的0而已，不会觉得有什么奇怪的
    printf("%d\n",c);
#endif

#if 0
    int a = 128;  //000...1000 0000
    char c = a;         //1000 0000 补码  
                        //0111 1111 反码
                        //0000 0000 原码（是0又不是0，如果是0，那么它的补码应该和原码相同，显然两者不相同，又因为它的补码是个负数，所以从这个角度可以理解为-0）
    //通过这个例子可以解答为什么有符号char比无符号char少一个数,这个少的数就是补码为1000 0000的数，既然它补码表示一个负数，那么它本质上一定是一个负数，于是人为规定，最高位这个1既把它当符号位，又把它当数据位，所以得出-128
    printf("%d\n",c);
    //所以有符号char真正表示范围为-(2^7)~2^7-1即-128~127
    /*推广到一般：
        int：-(2^31)~2^31-1
        short：-(2^15)~2^15-1
        long：-(2^63)~2^63-1
    */
#endif

/*浮点型*/
    //计算机的小数不能进行等于判断
    //计算机不认小数点
    /*
        二进制  十进制
        10      2^1
        100     2^2
        1000    2^3
        0.1     2^-1（0.5）
        0.01    2^-2（0.25）
        0.001   2^-3（0.125）
        以此类推
    */   
#if 0
    if(0.1 + 0.2 == 0.3)
    {
        printf("相等\n");
    }
    else
    {
        printf("不相等\n");
    }
    //0.1在二进制世界里是无限循环小数，是个近似值
    //所以说计算机里的大部分小数都是近似值

    if(0.25 + 0.5 == 0.75)
    {
        printf("相等\n");
    }
    else
    {
        printf("不相等\n");
    }
#endif

#if 0
    //在二进制小数里，整数部分有的话只能取1    
    //float单精度   1（符号位） + 8（指数位） + 23（有效数字位）
    //double双精度  1 + 11 + 52
    //long double

    printf("float: %ld\n",sizeof(float));
    printf("double: %ld\n",sizeof(double));
    printf("long double: %ld\n",sizeof(long double));
#endif

#if 0
    //无符号整型
    char c = 129;
    unsigned char d = c;
    printf("%d\n",d);   
#endif

#if 1
    char c = 129;
    printf("%u\n",c); //打印是补码
#endif

#if 0
    unsigned char c = 129;
    printf("%u\n",c);   //以无符号整型打印
#endif

    return 0;
}